-- UITrainingMain
-- Create by zouyb
-- 训练室界面

require "game/ui/form/training/UITrainingHeroSelect"
require "game/ui/form/training/UITrainingHeroUpgrade"
require "game/ui/form/hero/UIHeroUpgradeRankEffect"
require "game/ui/form/training/UITrainingItemDesc"

-- UITrainingMain继承自Layer
UITrainingMain = class("UITrainingMain", function()
    return cc.Layer:create();
end);

function UITrainingMain.create(classId)
    return UITrainingMain.new(classId);
end

-- 内部函数声明
local resize;

-- 构造函数
function UITrainingMain:ctor(classId)
    -- 初始化
    self:setName("UITrainingMain");
    local node = cc.CSLoader:createNode("layout/training/TrainingMain.csb");
    self:addChild(node);
    self.node = node;
    self.lastState = TrainingM.getState();
    self.classId = classId;

    --self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    self.descLabel = findChildByName(self.node, "CT/desc");
    self.desc2Label = findChildByName(self.node, "CT/desc2");
    self.desc3Label = findChildByName(self.node, "CT/desc3");

    -- 注册事件处理回调函数
    EventMgr.removeAll("UITrainingMain");
    self:registerEventCallback()

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw();

    -- 适配
    resize(node);
end

-- 适配
function resize(node)
    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 重绘英雄星级
function UITrainingMain:redrawHeroStar(heroFrame, classId)
    local starNode = findChildByName(heroFrame, "star_node");
    local hero = PetM.getMyPet(classId);
    if not hero then
        return;
    end

    -- 获取英雄阶位
    local starNum = hero:getRank();
    local maxStarNum = PetM.getMaxUpgradeRank();
    if maxStarNum < 1 then
        maxStarNum = 1;
    end

    -- 如果是已经升级完成了，那么多显示一颗星星
    -- 因为这时候实际上宠物是还没进阶的，所以需要特殊处理下
    if TrainingM.getState() == TrainingM.TRAINING_STATE_FINISH then
        starNum = starNum + 1;
    end

    if maxStarNum < starNum then
        maxStarNum = starNum;
    end

    -- 生成星星层，直接挂到结点上
    local lightStarPath = "images/ui/symbol/star_little.png";
    local darkStarPath  = "images/ui/symbol/star_little2.png";
    -- 如果冈布奥已觉醒，使用橙色的星星
    if AwakeM.isCarved(classId) then
        lightStarPath = "images/ui/symbol/star_little3.png";
    end

    local layer = createStarLayerEx(starNum, maxStarNum, lightStarPath, darkStarPath, "center", -0.7);
    if not layer then
        return;
    end

    if TrainingM.getState() == TrainingM.TRAINING_STATE_UPGRADING then
        layer = createStarLayer(starNum, lightStarPath, "center", -0.7);
    end

    starNode:removeAllChildren();
    starNode:addChild(layer);

    local starShine = heroFrame:getChildByName("star_shine");
    starShine:loadTexture("images/ui/symbol/star_little.png");
    starShine:stopAllActions();
    starShine:setVisible(false);

    if TrainingM.getState() == TrainingM.TRAINING_STATE_UPGRADING then
        starShine:setVisible(true);
        starShine:setPosition(starNode:getPositionX() + layer:getContentSize().width / 2 - starShine:getContentSize().width / 4, starNode:getPositionY());
        -- 星星放大缩小效果
        local action = cc.Sequence:create(cc.ScaleTo:create(0.5, 1.3), cc.ScaleTo:create(0.5, 1));
        starShine:runAction(cc.RepeatForever:create(action));
    end
end

-- 重绘
function UITrainingMain:redraw()
    local node = self.node;
    local CT   = node:getChildByName("CT");
    local BT   = node:getChildByName("BT");

        -- 显示标题
    local titleLabel = findChildByName(node, "CT/title");
    TextStyleM.setTitleStyle(titleLabel);
    local level = TrainingM.getLevel();
    titleLabel:setString(getLocStr("training_room"));

    -- 钻石信息
    local btGemIcon = findChildByName(BT, "gem/icon");
    local btGemNum = findChildByName(BT, "gem/num");
    TextStyleM.setOutlineStyle(btGemNum, TextStyleM.TEXT_OUTLINE_SIZE, TextStyleM.TEXT_OUTLINE_COLOR_DARK);
    TextStyleM.setTextStyle(btGemNum, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_WHITE);
    btGemNum:setString(tostring(ME.user:queryAttrib("gem")));
    btGemIcon:setVisible(false);
    btGemNum:setVisible(false);

    local heroId = self.classId;

    if not heroId then
        heroId = TrainingM.getHeroId();
        self.classId = heroId;
    end

    -- 显示星星
    local heroFrame = findChildByName(CT, "hero_frame");
    local starNode = findChildByName(heroFrame, "star_node");
    local starShine = heroFrame:getChildByName("star_shine");
    starNode:setVisible(false);
    starShine:setVisible(false);
    self:redrawHeroStar(heroFrame, heroId);

        -- 获取当前训练室信息
    local icon = findChildByName(CT, "hero_frame/icon");
    local light = findChildByName(CT, "hero_frame/light");
    icon:stopAllActions();
    icon:removeAllChildren();
    icon:setVisible(true);
    light:stopAllActions();
    light:removeAllChildren();

    if heroId == 0 then
        icon:setVisible(false);
        playLearnSkillHintEffect(light, -2, 0);
    else
        -- 加载英雄头像
        local pet = PetM.getMyPet(heroId);
        local fileName = pet:getIcon();
        local iconPath = getHeroIconPath(fileName);
        icon:loadTexture(iconPath);
        icon:setVisible(true);

        starNode:setVisible(true);
        icon:setOpacity(255);
    end

    -- 显示描述
    TextStyleM.setSubheadStyle(self.descLabel);

    -- 按钮上的文字
    local btnOk = findChildByName(node, "CT/btn_ok");
    TextStyleM.setTextStyle(btnOk, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnOk:setTitleText(getLocStr("btn_text_ok"));

    if heroId == 0 then
        btnOk:setBright(false);
        btnOk:setTouchEnabled(false);
    else
        btnOk:setBright(true);
        btnOk:setTouchEnabled(true);
    end

    -- 加速信息默认不显示
    local boostLabel = findChildByName(self.node, "CT/btn_ok/boost_label");
    local gemIcon = findChildByName(self.node, "CT/btn_ok/gem_icon");
    local amountLabel = findChildByName(self.node, "CT/btn_ok/gem_amount");
    boostLabel:setVisible(false);
    gemIcon:setVisible(false);
    amountLabel:setVisible(false);

    -- 隐藏进阶完成光效
    local finishLight = findChildByName(self.node,"CT/finish_light");
    finishLight:setVisible(false);

    self:stopAllActions();

    finishLight:stopAllActions();
    heroFrame:setTouchEnabled(false);

    -- 停止跳动
    setJumpStop("trainingMain", true);

    -- 宠物模型
    local heroModel = findChildByName(self.node,"CT/hero_frame/model_node");
    heroModel:stopAllActions();
    heroModel:setVisible(false);
    heroModel:removeAllChildren();

    -- 绘制冈布奥模型
    if heroId ~= 0 then
        local pet = PetM.getMyPet(heroId);
        local modelId = pet:getModelId();
        local offsetX = PetM.queryModel(modelId, "offset_x");
        local offsetY = PetM.queryModel(modelId, "offset_y");
        local iconPath = getHeroIconPath(PetM.queryModel(modelId, "icon"));
        local scale = 0.8 * PetM.queryModel(modelId, "model_scale");
        local modelAnim = createHeroModel(modelId, icon, heroModel, scale, iconPath, offsetX, offsetY);

        if modelAnim ~= nil then
            local function playAtkAnim()
                local rand = math.random(1, 2);
                local heroDisplay = findChildByName(heroModel, "HeroDisplay");

                if rand == 1 then
                    -- 播放施法动作
                    heroDisplay:switchAction(HERO_ACTION_CAST_ME);
                else
                    -- 播放攻击动作
                    heroDisplay:switchAction(HERO_ACTION_ATTACK);
                end

                -- 延迟播放攻击动作
                local delayFix = math.random(5, 10);
                performWithDelay(heroModel, playAtkAnim, delayFix);
            end

            heroModel:setVisible(true);

            playAtkAnim();
            --performWithDelay(heroFrame, playAtkAnim, delayFix);
        end
    end

    if type(self.desc2Label.initPosition) == "table" then
        local pos = self.desc2Label.initPosition;
        self.desc2Label:setPosition(cc.p(pos.x, pos.y));
    else
        self.desc2Label.initPosition = self.desc2Label:getPosition();
    end

    if type(self.desc3Label.initPosition) == "table" then
        local pos = self.desc3Label.initPosition;
        self.desc3Label:setPosition(cc.p(pos.x, pos.y));
    else
        self.desc3Label.initPosition = self.desc3Label:getPosition();
    end

    -- 获取训练状态
    local state = TrainingM.getState();

    if state == TrainingM.TRAINING_STATE_FINISH then
        self.desc2Label:setVisible(false);
        self.desc3Label:setVisible(true);
    else
        self.desc2Label:setVisible(true);
        self.desc3Label:setVisible(false);
    end

    -- 状态变化的光效
    if self.lastState ~= state and state ~= TrainingM.TRAINING_STATE_PREPARE then
        self.lastState = state;

        playEffect(heroFrame, 1180, 80, 85);

        self.desc2Label:stopAllActions();
        self.desc3Label:stopAllActions();
        self:descLabelFlyIn(self.desc2Label);
        self:descLabelFlyIn(self.desc3Label);
    end

    if state == TrainingM.TRAINING_STATE_PREPARE then
        TextStyleM.setSubheadStyle(self.desc2Label);
        -- 还未开始
        self.descLabel:setString(getLocStr("select_pet_to_upgrade"));
        self.desc2Label:setString(string.format(getLocStr("max_rank_to_upgrade"), level + 1));

        heroFrame:setTouchEnabled(true);
    elseif state == TrainingM.TRAINING_STATE_FINISH then

        TextStyleM.setTextStyle(self.desc3Label, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
        self.desc3Label:setString(getLocStr("slime_upgrade_finish"));
        convertTextToArtWord(self.desc3Label, "images/ui/text_mask/text_mask3.png", TextStyleM.TEXT_COLOR_DARK_BROWN, TextStyleM.TEXT_OUTLINE_COLOR_DARK);

        -- 进阶已完成
        self.descLabel:setString(string.format(getLocStr("pet_is_upgrading"), PetM.query(heroId, "name")));

        -- 进阶完成光效可见
        finishLight:setVisible(true);

        -- 光效旋转效果
        local action = cc.RotateBy:create(5, 360);
        finishLight:runAction(cc.RepeatForever:create(action));

        -- 字体跳动
        local nameCount = string.getWCharCount(self.desc3Label:getString());
        setArtWordJump(nameCount, self.desc3Label, self.node, "trainingMain", 0.2);

    elseif state == TrainingM.TRAINING_STATE_UPGRADING then
        -- 进阶中
        self.descLabel:setString(string.format(getLocStr("pet_is_upgrading"), PetM.query(heroId, "name")));

        btGemIcon:setVisible(true);
        btGemNum:setVisible(true);

        TextStyleM.setSubheadStyle(self.desc2Label);

        -- 开始定时更新
        self:startTick();
    end
end

-- 开始定时更新
function UITrainingMain:startTick()
    local btnOk = findChildByName(self.node, "CT/btn_ok");

    local function tick()
        if TrainingM.getState() ~= TrainingM.TRAINING_STATE_UPGRADING then
            self:redraw();
        else
            -- 当前剩余时间
            local finishTime = TrainingM.getFinishTime();
            local serverTime = TimeM.getServerTime();
            local leftTime = finishTime - serverTime;
            if leftTime < 0 then
                leftTime = 0;
            end

            local hours = math.floor(leftTime / 3600);
            local mins =  math.floor((leftTime % 3600) / 60);
            local secs =  math.floor((leftTime % 3600) % 60);

            local desc = string.format(getLocStr("slime_upgrading"), hours, mins, secs);

            -- 进阶中
            --TextStyleM.setSubheadStyle(self.desc2Label);
            self.desc2Label:setString(desc);

            -- 显示加速完成
            btnOk:setTitleText("");
            self:showBoostText(leftTime);

            if leftTime > 0 then
                performWithDelay(self, tick, 1);
            else
               self:redraw();
            end
        end
    end

    tick();
end

-- 显示加速完成文字
function UITrainingMain:showBoostText(leftTime)
    -- 显示加速
    local boostLabel = findChildByName(self.node, "CT/btn_ok/boost_label");
    TextStyleM.setTextStyle(boostLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, nil, nil, nil, nil, nil, true);
    boostLabel:setString(getLocStr("slime_upgrade_boost"));
    boostLabel:setVisible(true);

    -- 消耗价格
    local heroId = self.classId;
    local pet = PetM.getMyPet(heroId);
    local cost = FormulaM.invoke("CALC_PET_UPGRADE_BOOST_COST", pet, leftTime);
    local amount = cost[3];
    self.gemAmout = amount;
    local amountLabel = findChildByName(self.node, "CT/btn_ok/gem_amount");
    TextStyleM.setTextStyle(amountLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, nil, nil, nil, nil, nil, true);
    amountLabel:setString(tostring(amount));
    amountLabel:setVisible(true);

    -- 钻石不足时，显示红色
    local curGem = ME.user:queryAttrib("gem");
    if curGem < self.gemAmout then
        amountLabel:setTextColor(TextStyleM.TEXT_COLOR_LIGHT_RED);
    else
        amountLabel:setTextColor(TextStyleM.TEXT_COLOR_BROWN_YELLOW);
    end

    -- 钻石图标对齐
    local gemIcon = findChildByName(self.node, "CT/btn_ok/gem_icon");
    gemIcon:setPositionX(amountLabel:getPositionX() - amountLabel:getContentSize().width - 30);
    gemIcon:setVisible(true);
end

-- 注册事件处理回调函数
function UITrainingMain:registerEventCallback()
    -- 注册事件
    EventMgr.register("UITrainingMain", event.TRAINING_INFO_UPDATED, function()
        self.classId = TrainingM.getHeroId();
        self:redraw();
    end);

    -- 注册英雄升阶的回调
    EventMgr.register("UITrainingMain", event.UPGRADE_PET_RANK, function(args)
        self:whenUpgradeRank(args);
        self:redraw();
    end)

    -- 注册获得焦点的回调
    EventMgr.register("UITrainingMain", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UITrainingMain" then
            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_MONEY, TOPMENU_FRAME_GEM);
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            EventMgr.removeAll("UITrainingMain");

            -- show bottom
            local uiTalentMain = UIMgr.getCurrentScene():getFormByName("UITalentMain");
            if uiTalentMain then
                uiTalentMain:showButtons();
            end
        elseif eventType == "enter" then
            -- hide bottom
            local uiTalentMain = UIMgr.getCurrentScene():getFormByName("UITalentMain");
            if uiTalentMain then
                uiTalentMain:hideButtons();
            end
        end
    end);
end

-- 注册点击事件
function UITrainingMain:registerTouchEvent()
    local node = self.node;

    local hero_frame = findChildByName(node, "CT/hero_frame");
    hero_frame:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            if TrainingM.getFinishTime() ~= -1 then
                -- 已经在升阶或者升阶已完成，无法再选择
                -- 显示升阶详细信息
                local uiItemDesc = UITrainingItemDesc.create(TrainingM.getHeroId());
                UIMgr:getCurrentScene():addForm(uiItemDesc);
                AudioM.playFx("button_spell");
                return;
            end

            -- 打开英雄选择界面
            local uiForm = UITrainingHeroSelect.create();
            UIMgr.getCurrentScene():addForm(uiForm);
            AudioM.playFx("ui_open1");
        end
    end);

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");

            -- 如果当前英雄还没开始升阶，则取消升阶
            if TrainingM.getState() == TrainingM.TRAINING_STATE_PREPARE then
                Operation.cmd_pet_cancel_training();
            end

            -- 关闭当前界面
            UIMgr.getCurrentScene():removeFormByName("UITrainingMain");
            AudioM.playFx("button_return");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册确认按钮点击事件
    local btnOk = findChildByName(node, "CT/btn_ok");
    btnOk:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");
            local heroId = self.classId;
            if heroId == 0 then
                alert(getLocStr("please_select_a_pet"));
                return;
            end

            local state = TrainingM.getState();

            if state == TrainingM.TRAINING_STATE_PREPARE then
                local ret = TrainingM.canUpgrade(heroId);
                if ret ~= true then
                    if ret == "hero_upgrade_hint" then
                        -- 训练室等级不足，提示玩家具体升级信息
                        local areaId = FormulaM.invoke("GET_TREE_BRANCH_DROP_MAP", ME.user, TrainingM.getLevel() + 1);
                        local mapName = DungeonAreaM.query(areaId, "name");
                        local msg = string.format(getLocStr(ret), PetM.query(heroId, "name"), mapName);

                        showHint2(getLocStr("slime_note"), msg);
                        AudioM.playFx("button_spell");
                        return;
                    end

                    return alert(getLocStr(ret));
                end

                -- 选择英雄
                Operation.cmd_pet_prepare_training(heroId);

                -- 已选定，打开升阶确认界面
                local uiForm = UITrainingHeroUpgrade.create(heroId);
                UIMgr.getCurrentScene():addForm(uiForm);
            elseif state == TrainingM.TRAINING_STATE_FINISH then
                -- 已完成
                Operation.cmd_pet_finish_training(heroId);

                PetM.upgradeRank(heroId);
            else
                local curGem = ME.user:queryAttrib("gem");
                if curGem < self.gemAmout then
                    -- 钻石不足提示
                    showGemLackConfirm();
                    return;
                end

                -- 进行中
                local okFunc = function()
                    -- 加速升阶
                    Operation.cmd_pet_boost_training(heroId);
                end

                local tipTxt = string.format(getLocStr("slime_upgrade_boost_comfirm"), self.gemAmout or 0);
                confirm2(CONFIRM_TYPE_OK, getLocStr("slime_upgrade_boost"), tipTxt, okFunc);
            end
        end
    end);
end

-- 英雄升阶的回调
function UITrainingMain:whenUpgradeRank(args)
    if args["class_id"] == self.classId then
        local pet = PetM.getMyPet(self.classId);
        -- 显示升级光效
        local starNum = pet:getRank();
        AudioM.playFx("new_level");

        local parameters = {};
        parameters.classId = self.classId;
        parameters.starNum = starNum;

        local specialProp = FormulaM.invoke("PET_SPECIAL_PROP", self.classId, pet:getRank() - 1);
        local specialPropValue = specialProp[3] or 0;

        parameters.specialProp = specialProp;
        parameters.arr = {
            {"talent_skill_level", 1},
            {"attack", pet:getUpRankAddAttack()},
            {"magic", pet:getUpRankAddMagic()},
            {"max_hp", pet:getUpRankAddMaxHp()},
            {"max_mp", pet:getUpRankAddMaxMp()},
            {"special_prop", specialPropValue},
            {"career_type", pet:getUpRankAddCareerType()},};

        if UIMgr.getCurrentScene():isOpen("UIHeroUpgradeRankEffect") then
            UIMgr.getCurrentScene():removeFormByName("UIHeroUpgradeRankEffect");
        end
        local uiHeroUpgradeRankEffect = UIHeroUpgradeRankEffect.create(parameters);
        UIMgr.getCurrentScene():addForm(uiHeroUpgradeRankEffect);
    end
end

-- 描述文本飞入
function UITrainingMain:descLabelFlyIn(label)
    local duration = 0.2;
    local offsetX = DESIGN_WIDTH;
    local oldPosX = 0;
    local oldPosY = label:getPositionY();
    label:setPosition(cc.p(oldPosX - offsetX, oldPosY)); -- 从左边飞入

    local function play()
        local moveUp = cc.EaseIn:create(cc.MoveTo:create(duration, cc.p(oldPosX, oldPosY + 5)), 0.3);
        local moveDown = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPosX, oldPosY - 3)), 0.3);
        local moveUp2 = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(oldPosX, oldPosY)), 0.3);
        local action = cc.Sequence:create(moveUp ,moveDown, moveUp2);
        label:runAction(action);
    end

    label:stopAllActions();
    performWithDelay(label, play, 0.2);
end

